package com.onesports.intelligent.k12.polarlight.service.order;

import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryV3Result;
import com.onesports.intelligent.k12.polarlight.annotation.DistributedLock;
import com.onesports.intelligent.k12.polarlight.constant.BizConstants;
import com.onesports.intelligent.k12.polarlight.constant.LockConstants;
import com.onesports.intelligent.k12.polarlight.domain.dto.sys.WxUserPurseChangeDTO;
import com.onesports.intelligent.k12.polarlight.domain.entity.sys.WxPayOrder;
import com.onesports.intelligent.k12.polarlight.enums.TradeTypeEnum;
import com.onesports.intelligent.k12.polarlight.mapper.sys.WxPayOrderMapper;
import com.onesports.intelligent.k12.polarlight.service.wx.WxUserPurseService;
import com.onesports.intelligent.k12.polarlight.util.WxPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Wu
 */
@Service
@Slf4j
public class PayOrderCallBackService {

    @Resource
    private WxPayOrderMapper wxPayOrderMapper;

    @Resource
    private WxUserPurseService wxUserPurseService;


    /**
     * 处理 MarketOrderPay 对象
     *
     * @param result 微信支付结果
     * @param pay    MarketOrderPay 对象
     */
    @DistributedLock(value = LockConstants.LOCK_MARKET_ORDER_PAY, keys = "#pay.tradeNo")
    @Transactional(rollbackFor = Exception.class)
    public void operateActivityPay(WxPayOrderQueryV3Result result, WxPayOrder pay){
        if (BizConstants.WX_PAY_SUCCESS.equals(result.getTradeState())) {
            pay.setPayAmount(new BigDecimal(result.getAmount().getPayerTotal()).divide(new BigDecimal(100), 2, RoundingMode.DOWN));
            pay.setPayTime(WxPayUtil.parseRfc3339(result.getSuccessTime()));
            pay.setSuccessTime(WxPayUtil.parseRfc3339(result.getSuccessTime()));
            pay.setTradeState(result.getTradeState());
            pay.setTradeType(result.getTradeType());
            pay.setTradeStateDesc(result.getTradeStateDesc());
            pay.setBankType(result.getBankType());
            pay.setSpOpenid(result.getPayer().getOpenid());
            pay.setTransactionId(result.getTransactionId());

            //优惠信息
            List<WxPayOrderQueryV3Result.PromotionDetail> promotionDetails = result.getPromotionDetails();
            if (CollectionUtils.isNotEmpty(promotionDetails)) {
                String couponId = StringUtils.join(promotionDetails.stream().map(p -> String.valueOf(p.getCouponId())).collect(Collectors.toList()), ",");
                int couponAmount = promotionDetails.stream().mapToInt(WxPayOrderQueryV3Result.PromotionDetail::getAmount).sum();
                pay.setCouponAmount(new BigDecimal(couponAmount).divide(new BigDecimal(100), 2, RoundingMode.DOWN));
                pay.setCouponId(couponId);
            }
            wxPayOrderMapper.updateById(pay);
            WxUserPurseChangeDTO changeDTO =  WxUserPurseChangeDTO.builder()
                    .tradeType(TradeTypeEnum.RECHARGE)
                    .wxUserId(pay.getWxUserId())
                    .operateTime(pay.getPayTime())
                    .income(true)
                    .tradeNo(pay.getTradeNo())
                    .transactionId(pay.getTransactionId())
                    .amount(pay.getOrderAmount())
                    .build();
            //财务变动
            wxUserPurseService.inOrOutPurse(changeDTO);
        }
    }
}
